﻿using System;
using System.Threading;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows;
using PRV_BO.Domain;
using System.Windows.Forms.DataVisualization.Charting;
using GeneralUtilities;

namespace PRV_UI
{
	public partial class MainForm : Form
	{
		//TODO: Bug on rotacion, no filtra  los que se rotan

		#region private variables
		private PotreroBO currentPotrero;
		private RotacionBO currentRotacion;
		private PresenterPRV presenterPRV;
		private BindingManagerBase bmbPotreros;
		private BindingManagerBase bmbRotaciones;
		private BindingManagerBase bmbOcupados;

		AutoCompleteStringCollection scDesde = new AutoCompleteStringCollection();
		AutoCompleteStringCollection scHacia = new AutoCompleteStringCollection();
		DateTime dt;

		private class eArgs
		{
			public string PotreroDesde { get; set; }
			public string PotreroHacia { get; set; }

			public bool FiltrarRotaciones { get; set; }
			public PotrerosCollection ListaPotreros { get; set; }

			public eArgs(bool fr) { FiltrarRotaciones = fr; }
			public eArgs(string pDesde, string pHacia, bool filtrarRotaciones) { PotreroDesde = pDesde; PotreroHacia = pHacia; FiltrarRotaciones = filtrarRotaciones; }
		}

		#endregion

		#region constructor

		public MainForm()
		{
			InitializeComponent();
			gridPotreros.AutoGenerateColumns = true;
			gridRotaciones.AutoGenerateColumns = true;

			bmbPotreros = this.BindingContext[this.bindingsourcePotreros];
			bmbPotreros.PositionChanged += new EventHandler(bmbPot_PositionChanged);

			bmbRotaciones = this.BindingContext[this.bindingsourceRotaciones];
			bmbRotaciones.PositionChanged += new EventHandler(bmbRot_PositionChanged);

			bmbOcupados = this.BindingContext[this.bindingSourceOcupados];
			bmbOcupados.PositionChanged += new EventHandler(bmbOcu_PositionChanged);
		}

		#endregion

		#region Binding Handlers
		private void bmbPot_PositionChanged(object sender, EventArgs e)
		{
			currentPotrero = (PotreroBO)this.bindingsourcePotreros.Current;
			if (currentPotrero != null)
			{
				bindingsourceRotaciones.DataSource = currentPotrero.Rotaciones;
				this.labelRotaciones.Text = "Rotaciones - " + currentPotrero.NombrePotrero;
			}

		}

		private void bmbOcu_PositionChanged(object sender, EventArgs e)
		{
			PotreroBO potocu = (PotreroBO)this.bindingSourceOcupados.Current;
			this.bindingsourcePotreros.Position = this.bindingsourcePotreros.IndexOf(potocu);
			if (potocu != null)
			{
				this.textBoxDesde.Text = potocu.NombrePotrero;
				this.textBoxLote.Text = potocu.LoteOcupado;
			}
		}


		private void bmbRot_PositionChanged(object sender, EventArgs e)
		{
			currentRotacion = (RotacionBO)this.bindingsourceRotaciones.Current;
		}

		private void bindingsourcePotreros_AddingNew(object sender, AddingNewEventArgs e)
		{
			PotrerosCollection PC = (PotrerosCollection)bindingsourcePotreros.DataSource;
			PotreroBO pot = new PotreroBO(PC);
			pot.IsNew = true;
			pot.Area = string.Empty;
			e.NewObject = pot;
		}

		#endregion

		#region private methods

		private void refreshMoveDetails(bool filtraRotaciones = true)
		{
			try
			{
				dt = System.DateTime.Now;
				backgroundWorkerFullRefresh.RunWorkerAsync(new eArgs(filtraRotaciones));
				this.textBoxComentario.Text = this.textBoxHacia.Text = this.textBoxLote.Text = string.Empty;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void refreshMoveDetails(string desde, string hacia, bool filtrarRotaciones)
		{
			try
			{
				PresenterPRV.ActualizarRotacionesDePotrerosQueRotaron(desde, hacia, filtrarRotaciones);
				this.textBoxComentario.Text = string.Empty;

				PotrerosCollection qOcupados = PresenterPRV.PotrerosOcupados();
				RefreshOcupados(qOcupados);
				RefreshMainUI(qOcupados);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void backgroundFullRefresh_DoWork(object sender, DoWorkEventArgs e)
		{
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
			dt = System.DateTime.Now;
			eArgs ea = (eArgs)e.Argument;

			// Carga todos los potreros y sus rotaciones
			PresenterPRV.ResetAllPotrerosCache();
			PotrerosCollection allPotreros = PresenterPRV.allPotreros();
			PresenterPRV.AplicarFiltroAListaDeRotaciones(allPotreros, ea.FiltrarRotaciones);
		}

		private void backgroundWorkerFullRefresh_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			try
			{
				PotrerosCollection qOcupados = PresenterPRV.PotrerosOcupados(PresenterPRV.allPotreros());
				RefreshOcupados(qOcupados);
				RefreshMainUI(qOcupados);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void backgroundWorkerFiltrarRotaciones_DoWork(object sender, DoWorkEventArgs e)
		{
			PresenterPRV.AplicarFiltroAListaDeRotaciones(PresenterPRV.allPotreros(), ((eArgs)e.Argument).FiltrarRotaciones);
		}

		private void backgroundWorkerFiltrarRotaciones_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			this.bindingsourcePotreros.MoveNext();
			this.bindingsourcePotreros.MovePrevious();
		}


		#endregion

		#region EventHandlers

		private void Form1_Load(object sender, EventArgs e)
		{
			InitializeChart();
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.AppStarting;
		}

		private void btnAceptarPotreros_Click(object sender, EventArgs e)
		{
			PotrerosCollection pC = (PotrerosCollection)this.bindingsourcePotreros.DataSource;
			presenterPRV.GuardarPotrero(pC);
			PresenterPRV.ResetAllPotrerosCache();
			refreshMoveDetails(chkBoxFiltroRotaciones.Checked);
		}

		//private void buttonCargar_Click(object sender, EventArgs e)
		//{
		//    this.bindingsourcePotreros.DataSource = PresenterPRV.allPotreros();
		//    refreshMoveDetails(chkBoxFiltroRotaciones.Checked);
		//}

		private void buttonClose_click(object sender, EventArgs e)
		{
			this.Close();
		}

		private void btnDeletePotrero_Click(object sender, EventArgs e)
		{
			try
			{

				if (currentPotrero != null)
				{
					PotrerosCollection rC = (PotrerosCollection)this.bindingsourcePotreros.DataSource;
					if (currentPotrero.IsNew == true)
					{
						rC.Remove(currentPotrero);
						return;
					}

					if (MessageBox.Show("Seguro desea borrar este item ?", "Confirmacion", MessageBoxButtons.OKCancel) == DialogResult.OK)
					{
						presenterPRV.DeletePotrero(currentPotrero.NombrePotrero);
						rC.Remove(currentPotrero);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void buttonAceptarRotaciones_Click(object sender, EventArgs e)
		{
			RotacionesCollection rC = (RotacionesCollection)this.bindingsourceRotaciones.DataSource;
			presenterPRV.GuardarRotacion(rC);
			// Obtener nombre del potrero al que se le hizo cambios, y refrescar solo ese
			if (rC.Count > 0)
			{
//                refreshMoveDetails(currentPotrero.NombrePotrero, string.Empty, chkBoxFiltroRotaciones.Checked);
				refreshMoveDetails(rC.First().NombrePotrero, string.Empty, chkBoxFiltroRotaciones.Checked);
			}
		}

		private void buttonBorrarRotaciones_Click(object sender, EventArgs e)
		{
			currentRotacion = (RotacionBO)this.bindingsourceRotaciones.Current;
			currentPotrero = (PotreroBO)this.bindingsourcePotreros.Current;
			try
			{

				if (currentRotacion != null)
				{
					Int32 id = currentRotacion.ID;
					RotacionesCollection rC = (RotacionesCollection)this.bindingsourceRotaciones.DataSource;
					if (currentRotacion.IsNew)
					{
						rC.Remove(currentRotacion);
						return;
					}

					if (MessageBox.Show("Seguro desea borrar este item ?", "Confirmacion", MessageBoxButtons.OKCancel) == DialogResult.OK)
					{
						rC.Remove(currentRotacion);
						presenterPRV.DeleteRotacion(id);
						this.bindingsourcePotreros.Position = this.bindingsourcePotreros.IndexOf(currentPotrero);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}
		
		private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (tabControl1.SelectedIndex == 2)
			{
				//PresenterPRV pPrv = new PresenterPRV();
				this.bindingSourceAllRotaciones.DataSource = PresenterPRV.GetRotaciones();
				this.bindingSourceAllRotaciones.MoveLast();
				this.bindingSourceComentarios.DataSource = PresenterPRV.GetComentarios();
			}

			if (tabControl1.SelectedIndex == 4)
			{
				this.textBoxArchivo.Text = string.Format("PrvCe_{0}.sfd", DateTime.Now.Date.ToString("MMddyyyy"));
			}
		}

		private void btnRotar_Click(object sender, EventArgs e)
		{
			try
			{
				this.Cursor = Cursors.WaitCursor;

				RotArgs rArgs = new RotArgs()
				{
					PotreroOcupado = textBoxDesde.Text,
					PotreroaOcupar = textBoxHacia.Text,
					FechaMvto = dtFechaMvto.Value,
				};

				string msg = string.Empty;
				if (presenterPRV.ValidarMovimiento(rArgs, ref msg) == false)
				{
					MessageBox.Show(msg);
					return;
				}

				// there was a warning message in the validation
				if (msg != string.Empty)
				{ MessageBox.Show(msg); }

				presenterPRV.MoverLote(rArgs);
				refreshMoveDetails(rArgs.PotreroOcupado, rArgs.PotreroaOcupar, chkBoxFiltroRotaciones.Checked);
				textBoxHacia.Focus();
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Mensaje de Error");
			}
			finally
			{
				this.Cursor = Cursors.Default;
			}
		}

		private void buttonRefrescar_Click(object sender, EventArgs e)
		{
			refreshMoveDetails(chkBoxFiltroRotaciones.Checked);
		}

		private void buttonBorrarComentario_Click(object sender, EventArgs e)
		{
			try
			{
				ComentarioBO currentComentario = (ComentarioBO)this.bindingSourceComentarios.Current;

				if (currentComentario != null)
				{
					Int32 id = currentComentario.ID;
					ComentariosCollection rC = (ComentariosCollection)this.bindingSourceComentarios.DataSource;
					if (MessageBox.Show("Seguro desea borrar este item ?", "Confirmacion", MessageBoxButtons.OKCancel) == DialogResult.OK)
					{
						rC.Remove(currentComentario);
						presenterPRV.DeleteComentario(id);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}

		}

		private void buttonAceptarComentario_Click(object sender, EventArgs e)
		{
			ComentariosCollection rC = (ComentariosCollection)this.bindingSourceComentarios.DataSource;
			presenterPRV.GuardarComentario(rC);
		}

		private void MainForm_Shown(object sender, EventArgs e)
		{
			presenterPRV = new PresenterPRV();
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;

			this.btnMover.Enabled = false;

			RefreshOcupados(presenterPRV.GetPotrerosOcupados());
			refreshMoveDetails(chkBoxFiltroRotaciones.Checked);
			dtFechaMvto.Value = presenterPRV.GetUltFechaEntrada().Date.AddHours(16);
		}

		private void buttonCopia_Click(object sender, EventArgs e)
		{
			try
			{
				labelBackupStatus.Visible = true;
				labelBackupStatus.Text = "Creando copias...";
				CrearCopias();
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void CrearCopias()
		{
			string dbfile = ConfigUtilities.GetCEDbConnElement("prvCEEntities", "Data Source");
			string nombreArchivoCopia = textBoxArchivo.Text;
			string directorioLocalNube = textBoxDirNube.Text;

			BackupUtilities.CopiarADirNubeLocal(dbfile, nombreArchivoCopia, directorioLocalNube);

//            BackupUtilities.BackupCEDB(nombreArchivoCopia, dbfile, this, false, textBoxClave.Text);
		}

		//private void Recuperar_Click(object sender, EventArgs e)
		//{
		//	try
		//	{
		//		labelBackupStatus.Visible = true;
		//		labelBackupStatus.Text = "Obteniendo copia desde el servidor...";
		//		System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
		//		BackupUtilities.RestaurarCEDB("prvCEEntities", this, textBoxClave.Text);
		//		PresenterPRV.ResetAllPotrerosCache();
		//		refreshMoveDetails(chkBoxFiltroRotaciones.Checked);
		//		System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
		//	}
		//	catch (Exception ex)
		//	{
		//		MessageBox.Show(ex.Message);
		//	}
		//}

		private void button5_Click(object sender, EventArgs e)
		{
			Int32 ndias = Convert.ToInt32(maskedTextBox1.Text);
			string area = comboBoxSector.Text.Trim();
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
			BuildAndShowGuntcart(ndias, area);
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
		}

		private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (!Char.IsDigit(e.KeyChar) && e.KeyChar != 8)
			{
				e.Handled = true;
			}
		}

		private void cbSolo6Meses_CheckedChanged(object sender, EventArgs e)
		{
			backgroundWorkerFiltrarRotaciones.RunWorkerAsync(new eArgs(string.Empty, string.Empty, chkBoxFiltroRotaciones.Checked));
		}

		#endregion

		#region Helper methods

		private void RefreshMainUI(PotrerosCollection qOcupados)
		{
			this.bindingsourcePotreros.DataSource = PresenterPRV.allPotreros();
			this.bindingsourcePotreros.Position = 0;

			var q = PresenterPRV.ListaDeAreas(PresenterPRV.allPotreros());
			this.bindingSourceAreas.DataSource = q;

			PotrerosCollection qVacios = PresenterPRV.PotrerosVacios(PresenterPRV.allPotreros());
			LoadAutocompleteCollections(qOcupados, qVacios);
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
			this.btnMover.Enabled = true;
		}

		private void RefreshOcupados(PotrerosCollection qOcupados)
		{
			this.bindingSourceOcupados.DataSource = qOcupados;
			this.bindingSourceOcupados.Position = 0;
			if (this.textBoxHacia.Text.Trim() != string.Empty)
			{
				this.textBoxDesde.Text = this.textBoxHacia.Text;
				this.textBoxHacia.Text = string.Empty;
				this.bindingSourceOcupados.Position = this.bindingSourceOcupados.IndexOf((PotreroBO)qOcupados.First(wp => wp.NombrePotrero == this.textBoxDesde.Text));
				if (checkBoxAddDay.Checked)
				{
					this.dtFechaMvto.Value = this.dtFechaMvto.Value.AddDays(1);
				}
			}

			this.textBoxDesde.Text = ((PotreroBO)bindingSourceOcupados.Current).NombrePotrero;
		}

		private void LoadAutocompleteCollections(PotrerosCollection qOcupados, PotrerosCollection qVacios)
		{
			textBoxDesde.AutoCompleteCustomSource = null;
			textBoxHacia.AutoCompleteCustomSource = null;

			if (qOcupados != null)
			{
				scDesde.Clear();
				foreach (PotreroBO pot in qOcupados)
				{
					scDesde.Add(pot.NombrePotrero);
				}
			}

			if (qVacios != null)
			{
				scHacia.Clear();
				foreach (PotreroBO pot in qVacios)
				{
					scHacia.Add(pot.NombrePotrero);
				}
			}

			textBoxDesde.AutoCompleteCustomSource = scDesde;
			textBoxHacia.AutoCompleteCustomSource = scHacia;
		}

		private void textBoxHacia_Validating(object sender, CancelEventArgs e)
		{
			if (scHacia.Contains(textBoxHacia.Text) == false && textBoxHacia.Text.Trim() != string.Empty)
			{
				e.Cancel = true;
			}
		}

		private void textBoxDesde_Validating(object sender, CancelEventArgs e)
		{
			if (scDesde.Contains(textBoxDesde.Text) == false && textBoxDesde.Text.Trim() != string.Empty)
			{
				e.Cancel = true;
			}
		}

		private void InitializeChart()
		{
			System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
			((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit();
			this.SuspendLayout();

			this.chart1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(243)))), ((int)(((byte)(223)))), ((int)(((byte)(193)))));
			this.chart1.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.TopBottom;
			this.chart1.BorderlineColor = System.Drawing.Color.FromArgb(((int)(((byte)(181)))), ((int)(((byte)(64)))), ((int)(((byte)(1)))));
			this.chart1.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
			this.chart1.BorderlineWidth = 2;
			this.chart1.BorderSkin.SkinStyle = System.Windows.Forms.DataVisualization.Charting.BorderSkinStyle.Emboss;

			chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 7.0F, System.Drawing.FontStyle.Regular);
			chartArea1.AxisX.LabelStyle.IsEndLabelVisible = false;
			chartArea1.AxisX.IsLabelAutoFit = false;
			chartArea1.AxisX.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
			chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
			chartArea1.AxisX.Interval = 1;
			chartArea1.AxisX.IntervalAutoMode = IntervalAutoMode.FixedCount;
			chartArea1.AxisY.IsStartedFromZero = true;
			chartArea1.AxisY.IsLabelAutoFit = false;
			chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 6.0F, System.Drawing.FontStyle.Regular);
			chartArea1.AxisY.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
			chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
			chartArea1.BackColor = System.Drawing.Color.OldLace;
			chartArea1.BackSecondaryColor = System.Drawing.Color.White;
			chartArea1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
			chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
			chartArea1.Name = "Default";
			chartArea1.Position.Auto = true;
			chartArea1.Position.Height = 80F;
			chartArea1.Position.Width = 90F;
			chartArea1.Position.X = 5F;
			chartArea1.Position.Y = 6F;
			chartArea1.ShadowColor = System.Drawing.Color.Transparent;
			this.chart1.ChartAreas.Add(chartArea1);
			this.chart1.Location = new System.Drawing.Point(16, 48);
			this.chart1.Name = "chart1";
			this.chart1.Size = new System.Drawing.Size(600, 450);
			this.chart1.TabIndex = 0;
		}

		private void BuildAndShowGuntcart(int rangoDias, string area)
		{
			try
			{
				Dictionary<string, Int32> dictPotreros = new Dictionary<string, int>();
				DateTime currentDT = DateTime.Now.Date;
				RotacionDOCollection RC1 = presenterPRV.GetChartLabels(rangoDias, area);
				RotacionDOCollection RC2 = presenterPRV.GetChartData(rangoDias, area);
				Series s = new Series("Ocupacion");
				SetupSeries(s, "Ocupacion");

				chart1.Series[0].ChartType = SeriesChartType.RangeBar;
				chart1.Series[0]["PointWidth"] = "0.7";

				// Set Y axis Minimum and Maximum
				chart1.ChartAreas["Default"].AxisY.Minimum = currentDT.AddDays(-rangoDias).ToOADate();
				chart1.ChartAreas["Default"].AxisY.Maximum = currentDT.ToOADate();
				chart1.ChartAreas["Default"].Area3DStyle.Enable3D = false;
				Int32 j = 0;
				// Primero anadimos los labels al chart, de acuerdo a como mS Chart funcional
				foreach (RotacionDO rb in RC1)
				{
					s.Points.AddXY(j, rb.FechaEntrada, rb.FechaSalida);
					chart1.Series[0].Points[j].AxisLabel = rb.NombrePotrero;
					dictPotreros.Add(rb.NombrePotrero, j);
					j++;
				}

				// Luego anadimos el resto de puntos, que se encuentran en RC2
				foreach (RotacionDO rb in RC2)
				{
					dictPotreros.TryGetValue(rb.NombrePotrero, out j);
					s.Points.AddXY(j, rb.FechaEntrada, rb.FechaSalida);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void SetupSeries(Series series1, string nombrePotrero)
		{
			series1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
			series1.ChartArea = "Default";
			series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.RangeBar;
			series1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))));
			series1.CustomProperties = "PointWidth=0.7";
			series1.Name = nombrePotrero;
			series1.YValuesPerPoint = 10;
			if (this.chart1.Series.Count > 0)
			{ this.chart1.Series.RemoveAt(0); }
			this.chart1.Series.Add(series1);
		}

		#endregion

	}
}